﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace ModbusTest.Base
{
    public class LogProvider
    {
        public string LogPath { get; set; }
        private readonly object _lock = new object();

        StringBuilder logStr = new StringBuilder();
        int count = 0;

        public LogProvider(string log_path)
        {
            LogPath = log_path;
        }

        public void WriteLog(
            string msg,
            bool isRecord,
            bool isError = false,
            [CallerLineNumber] int line = 0,
            [CallerMemberName] string methodName = "",
            [CallerFilePath] string filePath = "")
        {
            if (!isRecord) return;

            WriteLog(new Log
            {
                Time = DateTime.Now,
                LogType = isError ? LogType.ERROR : LogType.LOG,
                Message = msg,

                ErrorFile = filePath,
                ErroMethod = methodName,
                ErrorLineNum = line,
            });
        }

        private void WriteLog(Log log)
        {
            lock (_lock)
            {
                count++;
                logStr.Append(log.ToString());

                if (count >= 100)
                {
                    SaveLog();

                    count = 0;
                    logStr.Clear();
                }
            }
        }

        public void Dispose()
        {
            SaveLog();
        }

        private void SaveLog()
        {
            string fileName = DateTime.Now.ToString("yyyyMMdd") + ".log";
            string filePath = Path.Combine(this.LogPath, fileName);

            // 清除3天前日志
            string delFile = DateTime.Now.AddDays(-3).ToString("yyyyMMdd") + ".log";
            string delFilePath = Path.Combine(this.LogPath, fileName);
            if (File.Exists(delFilePath))
                File.Delete(delFilePath);

            File.AppendAllText(filePath, logStr.ToString());
        }
    }

    internal class Log
    {
        public DateTime Time { get; set; }
        public string Message { get; set; }
        public LogType LogType { get; set; }

        public string ErrorFile { get; set; }
        public string ErroMethod { get; set; }
        public int ErrorLineNum { get; set; }

        public override string ToString()
        {
            if (this.LogType == LogType.LOG)
                return $"{Time.ToString("yyyy-MM-dd HH:mm:ss")}  [{LogType.ToString()}]  {Message}\r\n";

            if (this.LogType == LogType.ERROR)
                return $"{Time.ToString("yyyy-MM-dd HH:mm:ss")}  [{LogType.ToString()}]  {Message}\r\n" +
                    $"\t异常文件：{ErrorFile}\r\n" +
                    $"\t异常位置：{ErroMethod}  [Line：{ErrorLineNum}]\r\n";

            return base.ToString();
        }
    }

    internal enum LogType
    {
        LOG, ERROR
    }
}
